"""
restyt/__init__.py  - Resty is a RESTful distributed framework in python

Copyright: Zeng Ke, superisaac.ke@gmail.com
"""
import transport
from urlparse import urljoin

class Node:
    current_address = None
    _current_node = None

    @classmethod
    def current(cls):
        if cls._current_node is None:
            cls._current_node = cls(cls.current_address)
        return cls._current_node

    @classmethod
    def run(cls, address, *init_rests):
        cls.current_address = address
        node = cls.current()
        for r in init_rests:
            node.create(r)
        transport.run_server(node)

    @classmethod
    def is_current(cls, address):
        return cls.current_address == address

    def __init__(self, address):
        self.address = address
        self.resources = {}

    def get(self, url):
        return self.resources.get(url)

    def create(self, robj):
        self.resources[robj.url] = robj

    def delete(self, robj):
        if robj.url in self.resources:
            del self.resources[robj.url]

class RestException(Exception):
    pass

class RestRef(object):
    def __init__(self, node_address, refurl):
        self.node_address = node_address
        self.refurl = refurl
    def __str__(self):
        return 'ref-' + urljoin('http://%s/' % self.node_address, self.refurl)
    def __repr__(self):
        return repr(self.__str__())

    def _restobj(self):
        if Node.is_current(self.node_address):
            # Local node method
            n = Node.current()
            obj =  n.get(self.refurl)
            if obj is None:
                raise RestException("None")
            return obj
        else:
            # Remote node call
            return transport.NodeClient(self.node_address, self.refurl)

    def get(self, *args, **kwargs):
        robj = self._restobj()
        return robj.get(*args, **kwargs)

    def update(self, *args, **kwargs):
        robj = self._restobj()
        return robj.update(*args, **kwargs)

    def create(self, *args, **kwargs):
        robj = self._restobj()
        return robj.create(*args, **kwargs)

    def delete(self, *args, **kwargs):
        robj = self._restobj()
        return robj.delete(*args, **kwargs)
reference = RestRef

class RestObj:
    def __init__(self, url):
        self.url = url
        #Node.current().create(self)

    def reference(self):
        return RestRef(Node.current_address, self.url)

    def get(self, *args, **kwargs):
        raise RestException('Get not implemented')

    def update(self, *args, **kwargs):
        raise RestException('Update not implemented')

    def create(self, *args, **kwargs):
        raise RestException('Create not implemented')
    
    def delete(self, *args, **kwargs):
        raise RestException('Delete not implemented')


